<template>
	<el-dialog v-model="visible" :title="'进度配置'" :close-on-click-modal="false">
		<el-steps :active="active">
			<el-step title="步骤 1" description="构建reader" />
			<el-step title="步骤 2" description="构建writer" />
			<el-step title="步骤 3" description="字段映射" />
			<el-step title="步骤 4" description="构建" />
		</el-steps>
		<br />

		<el-form ref="dataFormRef" :model="dataForm" :rules="dataRules" label-width="100px" v-loading="formLoading">
			<el-scrollbar height="600px">
				<!-- reader -->
				<div v-show="active === 1">
					<el-form-item label="数据库源" prop="readerDatabaseId">
						<el-select placeholder="请选择" style="width: 100%" filterable v-model="dataForm.readerDatabaseId" @change="readerDatabaseChange">
							<el-option v-for="(item, index) in databaseDataList" :value="item.id" :label="item.name" :key="index"></el-option>
						</el-select>
					</el-form-item>
					<el-form-item label="数据库表名" prop="readerTables">
						<el-select placeholder="请选择" style="width: 100%" filterable v-model="dataForm.readerTables" @change="readerTablesChange">
							<el-option v-for="(item, index) in IntegrateList" :value="item.tableName" :label="item.tableName" :key="index">
								{{ item.tableName }}
								<span v-if="item.remarks">({{ item.remarks }})</span>
							</el-option>
						</el-select>
					</el-form-item>
					<el-form-item label="SQL语句" prop="querySql">
						<el-input
							type="textarea"
							style="width: 80%"
							:rows="4"
							v-model="dataForm.querySql"
							placeholder="sql查询，一般用于多表关联查询时才用"
						></el-input>
						<el-button type="primary" style="margin-left: 20px" @click="analysisColumnsSql">解析字段</el-button>
					</el-form-item>
					<el-form-item label="切分字段" prop="readerSplitPk">
						<el-input placeholder="切分主键" v-model="dataForm.readerSplitPk"></el-input>
					</el-form-item>
					<el-form-item label="表所有字段" prop="readerColumns">
						<el-checkbox
							style="margin-right: 20px"
							v-model="checkAllReader"
							:indeterminate="isIndeterminateReader"
							@change="handleCheckAllReaderChange"
							>全选</el-checkbox
						>
						<el-checkbox-group v-model="dataForm.readerColumns" @change="handleCheckedReaderChange">
							<el-checkbox v-for="city in readerColumnsList" :key="city" :label="city">{{ city }}</el-checkbox>
						</el-checkbox-group>
					</el-form-item>
					<el-form-item label="where条件" prop="whereParams">
						<el-input type="textarea" :rows="2" v-model="dataForm.whereParams" placeholder="where条件，不需要在加where"></el-input>
					</el-form-item>
				</div>
				<div v-show="active === 2">
					<el-form-item label="数据库源" prop="writerDatabaseId">
						<el-select placeholder="请选择" style="width: 100%" filterable v-model="dataForm.writerDatabaseId" @change="writerDatabaseChange">
							<el-option v-for="(item, index) in databaseDataList" :value="item.id" :label="item.name" :key="index"></el-option>
						</el-select>
					</el-form-item>
					<el-form-item label="数据库表名" prop="writerTables">
						<el-select placeholder="请选择" style="width: 100%" filterable v-model="dataForm.writerTables" @change="writerTablesChange">
							<el-option v-for="(item, index) in writerIntegrateList" :value="item.tableName" :label="item.tableName" :key="index">
								{{ item.tableName }}
								<span v-if="item.remarks">({{ item.remarks }})</span>
							</el-option>
						</el-select>
					</el-form-item>
					<el-form-item label="表所有字段" prop="writerColumns">
						<el-checkbox
							style="margin-right: 20px"
							v-model="checkAllWriter"
							:indeterminate="isIndeterminateWriter"
							@change="handleCheckAllWriterChange"
							>全选</el-checkbox
						>
						<el-checkbox-group v-model="dataForm.writerColumns" @change="handleCheckedWriterChange">
							<el-checkbox v-for="city in writerColumnsList" :key="city" :label="city">{{ city }}</el-checkbox>
						</el-checkbox-group>
					</el-form-item>
					<el-form-item label="前置SQL语句" prop="preSql">
						<el-input type="textarea" :rows="2" v-model="dataForm.preSql" placeholder="前置sql在insert之前执行"></el-input>
					</el-form-item>
					<el-form-item label="postSql" prop="postSql">
						<el-input type="textarea" :rows="2" v-model="dataForm.postSql" placeholder="多个用;分隔"></el-input>
					</el-form-item>
				</div>

				<div v-show="active === 3">
					<el-form-item label="源端字段" prop="readerColumns1">
						<el-checkbox
							style="margin-right: 20px"
							v-model="checkAllReader1"
							:indeterminate="isIndeterminateReader1"
							@change="handleCheckAllReaderChange1"
							>全选</el-checkbox
						>
						<el-checkbox-group v-model="dataForm.readerColumns1" @change="handleCheckedReaderChange1">
							<el-checkbox v-for="city in dataForm.readerColumns" :key="city" :label="city">{{ city }}</el-checkbox>
						</el-checkbox-group>
					</el-form-item>
					<el-form-item label="目标字段" prop="writerColumns1">
						<el-checkbox
							style="margin-right: 20px"
							v-model="checkAllWriter1"
							:indeterminate="isIndeterminateWriter1"
							@change="handleCheckAllWriterChange1"
							>全选</el-checkbox
						>
						<el-checkbox-group v-model="dataForm.writerColumns1" @change="handleCheckedWriterChange1">
							<el-checkbox v-for="city in dataForm.writerColumns" :key="city" :label="city">{{ city }}</el-checkbox>
						</el-checkbox-group>
					</el-form-item>
				</div>
				<div v-show="active === 4" style="height: 600px">
					<el-button type="primary" @click="buildJsonBtn">构建</el-button>
					<!-- <el-button @click="copyBtn">复制json</el-button> -->

					<div style="height: calc(100% - 60px); margin-top: 10px">
						<textarea style="width: 100%; border-width: 0; height: 100%" v-model="dataAccessJson" rows="25"></textarea>
						<!-- <DataStudioJson ref="dataStudioJsonRef"></DataStudioJson> -->
					</div>
				</div>
			</el-scrollbar>
		</el-form>

		<template #footer>
			<div style="text-align: center">
				<el-button v-if="active === 1" @click="visible = false"> 取消 </el-button>
				<el-button v-if="active > 1" @click="pre()"> 上一步 </el-button>
				<el-button type="primary" @click="next()" v-if="active > 0 && active < 4"> 下一步 </el-button>
				<!-- <el-button type="primary" @click="submitHandle()" v-if="active == 4"> 确定 </el-button> -->
			</div>
		</template>
	</el-dialog>
</template>
<script setup lang="ts">
import service from '@/utils/request'
import { ref, reactive, onMounted, watch, nextTick } from 'vue'
// import DataStudioJson from './data-studio-json.vue'
import { ElMessage, ElMessageBox } from 'element-plus'

import { getTableColumns, buildDataxJson, getSqlColumns } from '@/api/task-scheduling'
const emit = defineEmits(['refreActive', 'refreshData'])
const active = ref(1)
const visible = ref(false)
const formLoading = ref(true)

const pattern = /[`~!@#$^\-&*()=|{},\\\[\]\.<>\/?~！@#￥……&*（）——|{}【】。，、？\s]/g

const dataFormRef = ref()
const dataForm: any = reactive({
	id: '',
	// 数据库源id
	readerDatabaseId: '',
	// reader 表所有字段
	readerColumns: [],
	// 数据库表名
	readerTables: '',
	querySql: '',
	readerSplitPk: '',
	whereParams: '',
	// writer 数据源id
	writerDatabaseId: '',
	writerTables: '',
	// writer 表所有字段
	writerColumns: [],

	readerColumns1: [], // 源端字段
	writerColumns1: [], // 目标字段
	postSql: '',
	preSql: ''
})
const dataRules = ref({
	readerDatabaseId: [{ required: true, message: '必填项不能为空', trigger: 'blur' }],
	// readerTables: [
	// 	{
	// 		trigger: 'change',
	// 		validator: (rule, value, callback) => {
	// 			if ((value && !dataForm.querySql) || (!value && dataForm.querySql)) {
	// 				callback()
	// 			} else {
	// 				callback(new Error('数据库表名,SQL语句选填一项'))
	// 			}
	// 		}
	// 	}
	// ],
	// querySql: [
	// 	{
	// 		trigger: 'change',
	// 		validator: (rule, value, callback) => {
	// 			if ((value && !dataForm.readerTables) || (!value && dataForm.readerTables)) {
	// 				callback()
	// 			} else {
	// 				callback(new Error('数据库表名,SQL语句选填一项'))
	// 			}
	// 		}
	// 	}
	// ],
	writerDatabaseId: [{ required: true, message: '必填项不能为空', trigger: 'change' }],
	writerTables: [{ required: true, message: '必填项不能为空', trigger: 'change' }]
})

const dataAccessJson = ref('')
//vscode编辑器
// const dataStudioJsonRef = ref()

const pre = () => {
	if (active.value-- < 2) active.value = 1
}

const next = () => {
	if (active.value++ > 4) {
		active.value = 5
	} else if (active.value === 4) {
		// dataStudioJsonRef.value.setEditorValue(dataAccessJson.value)
	}
}

const init = async (dataJson, sourceTargetDbId) => {
	visible.value = true
	formLoading.value = false

	dataAccessJson.value = ''

	if (sourceTargetDbId) {
		dataForm.readerDatabaseId = Number(sourceTargetDbId.split(',')[0])
		dataForm.writerDatabaseId = Number(sourceTargetDbId.split(',')[1])
	}

	if (dataJson) {
		dataAccessJson.value = dataJson.replace(/\\\\n/g, '\n')

		const dataParseJson = JSON.parse(dataJson)
		if (dataParseJson.hasOwnProperty('job')) {
			dataForm.readerSplitPk = Object.hasOwnProperty.call(dataParseJson.job.content[0].reader.parameter, 'splitPk')
				? dataParseJson.job.content[0].reader.parameter.splitPk
				: ''

			dataForm.querySql = Object.hasOwnProperty.call(dataParseJson.job.content[0].reader.parameter.connection[0], 'querySql')
				? dataParseJson.job.content[0].reader.parameter.connection[0].querySql[0]
				: ''

			dataForm.querySql = dataForm.querySql.replace(/\\n/g, '\n')

			dataForm.whereParams = Object.hasOwnProperty.call(dataParseJson.job.content[0].reader.parameter, 'where')
				? dataParseJson.job.content[0].reader.parameter.where
				: ''

			dataForm.preSql = Object.hasOwnProperty.call(dataParseJson.job.content[0].reader.parameter, 'preSql')
				? dataParseJson.job.content[0].reader.parameter.preSql
				: ''

			dataForm.postSql = Object.hasOwnProperty.call(dataParseJson.job.content[0].reader.parameter, 'postSql')
				? dataParseJson.job.content[0].reader.parameter.postSql
				: ''

			if (dataParseJson.job.content[0].reader.parameter.connection[0].table) {
				dataForm.readerTables =
					dataParseJson.job.content[0].reader.parameter.connection[0].table[0].split('.')[
						dataParseJson.job.content[0].reader.parameter.connection[0].table[0].split('.').length - 1
					]

				await analysisColumns()
			} else {
				await analysisColumnsSql()
			}
			if (dataParseJson.job.content[0].writer.parameter.connection[0].table) {
				dataForm.writerTables =
					dataParseJson.job.content[0].writer.parameter.connection[0].table[0].split('.')[
						dataParseJson.job.content[0].writer.parameter.connection[0].table[0].split('.').length - 1
					]
				await writerColumnsData()
			}

			if (dataForm.readerDatabaseId) {
				getIntegrate(dataForm.readerDatabaseId)
			}
			if (dataForm.writerDatabaseId) {
				getWriterIntegrate(dataForm.writerDatabaseId)
			}

			dataForm.readerColumns = []
			if (dataParseJson.job.content[0].reader.parameter.column) {
				dataParseJson.job.content[0].reader.parameter.column.forEach(item => {
					dataForm.readerColumns.push(item.replace(pattern, ''))
				})

				if (dataForm.readerColumns.length == readerColumnsList.value.length) {
					checkAllReader.value = true
					isIndeterminateReader.value = false
				} else {
					checkAllReader.value = false
					isIndeterminateReader.value = true
				}
			}

			dataForm.writerColumns = []
			if (dataParseJson.job.content[0].writer.parameter.column) {
				dataParseJson.job.content[0].writer.parameter.column.forEach(item => {
					dataForm.writerColumns.push(item.replace(pattern, ''))
				})

				if (dataForm.writerColumns.length == writerColumnsList.value.length) {
					checkAllWriter.value = true
					isIndeterminateWriter.value = false
				} else {
					checkAllWriter.value = false
					isIndeterminateWriter.value = true
				}
			}

			dataForm.readerColumns1 = dataForm.readerColumns
			dataForm.writerColumns1 = dataForm.writerColumns
		} else {
			// 重置表单数据
			// nextTick(() => {
			// 	if (dataFormRef.value) {
			// 		dataFormRef.value.resetFields()
			// 	}
			// })
			dataForm.readerDatabaseId = ''
			dataForm.writerDatabaseId = ''

			dataForm.readerTables = ''
			dataForm.writerTables = ''

			dataForm.querySql = ''
			dataForm.readerSplitPk = ''
			dataForm.whereParams = ''
			dataForm.postSql = ''
			dataForm.preSql = ''

			dataForm.readerColumns = []
			dataForm.writerColumns = []

			databaseDataList.value = []
			IntegrateList.value = []
			writerIntegrateList.value = []
			readerColumnsList.value = []
			writerColumnsList.value = []
		}
	} else {
		// 重置表单数据
		// nextTick(() => {

		// 	if (dataFormRef.value) {

		// 		dataFormRef.value.resetFields()
		// 	}
		// })
		dataForm.readerDatabaseId = ''
		dataForm.writerDatabaseId = ''

		dataForm.readerTables = ''
		dataForm.writerTables = ''

		dataForm.readerColumns = []
		dataForm.writerColumns = []

		dataForm.querySql = ''
		dataForm.readerSplitPk = ''
		dataForm.whereParams = ''
		dataForm.postSql = ''
		dataForm.preSql = ''

		databaseDataList.value = []
		IntegrateList.value = []
		writerIntegrateList.value = []
		readerColumnsList.value = []
		writerColumnsList.value = []
	}

	active.value = 1

	// 第一步
	getDatabase()
}

const getActive = () => {
	return active.value
}

const getJson = () => {
	return dataAccessJson.value
}

watch(active, (newV, oldV) => {
	emit('refreActive')
})

const databaseDataList = ref([]) // 数据库源
const IntegrateList = ref([]) // 数据库表名
const writerIntegrateList = ref([]) // 数据库表名
// 第一步
const checkAllReader = ref(false)
const isIndeterminateReader = ref(true)
const readerColumnsList = ref([]) // 表所有字段
const handleCheckAllReaderChange = (val: boolean) => {
	dataForm.readerColumns = val ? readerColumnsList.value : []
	isIndeterminateReader.value = false
}

const handleCheckedReaderChange = (value: string[]) => {
	const checkedCount = value.length
	checkAllReader.value = checkedCount === readerColumnsList.value.length
	isIndeterminateReader.value = checkedCount > 0 && checkedCount < readerColumnsList.value.length
	dataForm.readerColumns = value
	dataForm.readerColumns1 = value
}

// 数据库源切换
const readerDatabaseChange = value => {
	dataForm.readerTables = ''
	getIntegrate(value)
}

// 第二步
const writerTables = ref('') // 数据库表名
const checkAllWriter = ref(false)
const isIndeterminateWriter = ref(true)
const writerColumnsList = ref([]) // 表所有字段

const handleCheckAllWriterChange = (val: boolean) => {
	dataForm.writerColumns = val ? writerColumnsList.value : []
	isIndeterminateWriter.value = false
}
const handleCheckedWriterChange = (value: string[]) => {
	const checkedCount = value.length
	checkAllWriter.value = checkedCount === writerColumnsList.value.length
	isIndeterminateWriter.value = checkedCount > 0 && checkedCount < writerColumnsList.value.length
	dataForm.writerColumns = value
	dataForm.writerColumns1 = value
}

const writerDatabaseChange = value => {
	dataForm.writerTables = ''
	getWriterIntegrate(value)
}

// 第三步
const checkAllReader1 = ref(true)
const isIndeterminateReader1 = ref(false)
const handleCheckAllReaderChange1 = (val: boolean) => {
	dataForm.readerColumns1 = val ? dataForm.readerColumns : []
	isIndeterminateReader1.value = false
}

const handleCheckedReaderChange1 = (value: string[]) => {
	const checkedCount = value.length
	checkAllReader1.value = checkedCount === dataForm.readerColumns.length
	isIndeterminateReader1.value = checkedCount > 0 && checkedCount < dataForm.readerColumns.length
}

const checkAllWriter1 = ref(true)
const isIndeterminateWriter1 = ref(false)

const handleCheckAllWriterChange1 = (val: boolean) => {
	dataForm.writerColumns1 = val ? dataForm.writerColumns : []
	isIndeterminateWriter1.value = false
}
const handleCheckedWriterChange1 = (value: string[]) => {
	const checkedCount = value.length
	checkAllWriter1.value = checkedCount === dataForm.writerColumns.length
	isIndeterminateWriter1.value = checkedCount > 0 && checkedCount < dataForm.writerColumns.length
}

//数据库源
const getDatabase = () => {
	service.get('data-integrate/database').then(res => {
		databaseDataList.value = res.data
	})
}

// reader
// 数据库表名
const getIntegrate = id => {
	service.get(`data-integrate/database/tables/${id}`, {}).then(res => {
		IntegrateList.value = res.data
	})
}

// writer 数据库表名
const getWriterIntegrate = id => {
	service.get(`data-integrate/database/tables/${id}`, {}).then(res => {
		writerIntegrateList.value = res.data
	})
}

const analysisColumns = async () => {
	readerColumnsList.value = []
	if (dataForm.readerDatabaseId && dataForm.readerTables) {
		await getTableColumns(dataForm.readerDatabaseId, dataForm.readerTables)
			.then(res => {
				formLoading.value = false
				res.data.forEach(element => {
					readerColumnsList.value.push(element.fieldName)
				})

				dataForm.readerColumns = readerColumnsList.value
				checkAllReader.value = true
				isIndeterminateReader.value = false
				dataForm.readerColumns1 = dataForm.readerColumns
			})
			.catch(() => {
				formLoading.value = false
			})
	}
}

const analysisColumnsSql = async () => {
	if (dataForm.querySql && dataForm.readerDatabaseId) {
		readerColumnsList.value = []
		const commentIndex = dataForm.querySql.replace(/--\s.*$/gm, '').trim()
		await getSqlColumns(dataForm.readerDatabaseId, ' select * from ( ' + commentIndex.replace(/\n/g, ' ') + ' ) mlsk where 1<>1')
			// await getSqlColumns(dataForm.readerDatabaseId, dataForm.querySql.replace(/\n/g, ' '))
			.then(res => {
				formLoading.value = false
				res.data.forEach(element => {
					readerColumnsList.value.push(element)
				})

				dataForm.readerColumns = readerColumnsList.value
				checkAllReader.value = true
				isIndeterminateReader.value = false
				dataForm.readerColumns1 = dataForm.readerColumns
			})
			.catch(() => {
				formLoading.value = false
			})
	}
}

const readerTablesChange = value => {
	formLoading.value = true
	dataForm.readerTables = value

	analysisColumns()
}

const writerTablesChange = value => {
	formLoading.value = true
	dataForm.writerTables = value
	writerColumnsData()
}

const writerColumnsData = async () => {
	writerColumnsList.value = []
	if (dataForm.writerDatabaseId && dataForm.writerTables) {
		await getTableColumns(dataForm.writerDatabaseId, dataForm.writerTables)
			.then(res => {
				formLoading.value = false
				res.data.forEach(element => {
					writerColumnsList.value.push(element.fieldName)
				})

				dataForm.writerColumns = writerColumnsList.value
				checkAllWriter.value = true
				isIndeterminateWriter.value = false
				dataForm.writerColumns1 = dataForm.writerColumns
			})
			.catch(() => {
				formLoading.value = false
			})
	}
}

// 构建
const buildJsonBtn = () => {
	let data = {
		readerDatasourceId: dataForm.readerDatabaseId,
		readerTables: [dataForm.readerTables],
		readerColumns: dataForm.readerColumns1,
		writerDatasourceId: dataForm.writerDatabaseId,
		writerTables: [dataForm.writerTables],
		writerColumns: dataForm.writerColumns1,
		rdbmsReader: {
			readerSplitPk: dataForm.readerSplitPk,
			whereParams: dataForm.whereParams,
			querySql: dataForm.querySql
		},
		rdbmsWriter: {
			preSql: dataForm.preSql,
			postSql: dataForm.postSql
		}
	}

	if (!dataForm.readerColumns1.length) {
		ElMessage.error({
			message: '请选择源端字段',
			duration: 500
		})

		return false
	}
	if (!dataForm.writerColumns1.length) {
		ElMessage.error({
			message: '请选择目标字段',
			duration: 500
		})

		return false
	}

	buildDataxJson(data).then(res => {
		const parseJson = JSON.parse(res.data)

		if (parseJson.job.setting.speed.hasOwnProperty('byte')) {
			delete parseJson.job.setting.speed['byte']
		}

		dataAccessJson.value = JSON.stringify(parseJson)
		ElMessage.success({
			message: '构建成功',
			duration: 500,
			onClose: () => {
				visible.value = false
				emit('refreshData')
			}
		})
		// dataStudioJsonRef.value.setEditorValue(res.data)
	})
}

const submitHandle = () => {
	dataFormRef.value.validate((valid: boolean) => {
		if (!valid) {
			ElMessage({
				message: '请将每一步的参数必填项填写完毕后再提交！',
				type: 'warning'
			})
			return false
		}
	})
	// dataAccessJson.value = dataStudioJsonRef.value.getEditorValue()
	if (!dataAccessJson.value) {
		ElMessage({
			message: '请构建Json！',
			type: 'warning'
		})
		return false
	}
	visible.value = false
	emit('refreshData')
}

const copyBtn = () => {
	// dataStudioJsonRef.value.copyBtn()
	ElMessage.success({
		message: '复制成功',
		duration: 500
	})
}

const getsourceTargetDbId = () => {
	const str = dataForm.readerDatabaseId + ',' + dataForm.writerDatabaseId + ''
	return str
}

defineExpose({
	init,
	getActive,
	getJson,
	active,
	getsourceTargetDbId
})
</script>
<style lang="scss" scoped></style>
